package extends1demo;

public class Test3 {
    public static void main(String[] args) {
        //1. 目标：认识方法重写，再搞清楚场景。
        Cat cat = new Cat();
        cat.cry();

        // 2.目标：方法重写的常见应用场景：子类重写Object的toString方法，以便返回对象的内容。
        cat.setName("小花");
        System.out.println(cat);
        // 3.目标：认识多态的代码。对象多态、行为多态。
        Animal cat1 = new Cat();
        cat1.cry();// 方法：编译看左边，运行看右边
        System.out.println(cat1.name);// 成员变量：编译看左边，运行也看左边
     // 1、多态的好处1: 右边对象是解耦合的。左边代码不变的情况下，换右边new 对象
        Animal dog = new Dog();
         dog.cry();
       // dog.selfDog();// 多态下的一个问题：多态下不能调用子类独有功能。

      //2.强制类型转换：可以解决多态下调用子类独有功能
        Dog dog2 = (Dog) dog;
        dog2.selfDog();

        Dog dog1 = new Dog();
        dog1.selfDog();
        //将接收类型改为Animal 就可以接收所有子类
        go(cat);
        go(dog);
    }
   /* 将动物送过来跑步  */
    public static void go(Animal animal){
        // 报错，多态下不能调用子类独有功能。
        animal.cry();
        // java建议强制转换前，应该判断对象的真实类型，再进行强制类型转换。
        if(animal instanceof Cat){
            ((Cat) animal).selfCat();//强制类型转换前，先判断类型
        }else if (animal instanceof Dog){
            ((Dog) animal).selfDog();
        }
    }
}

class Animal{
     String name="动物" ;
    public void cry(){
        System.out.println("动物会叫");
    }
    public void cry(String name){
        System.out.println(name);
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}
class Cat extends Animal{
     String name="小猫";
    // 方法重写: 方法名称，形参列表必须一样，这个方法就是方法重写。
    // 重写的规范：声明不变，重新实现。
    @Override// 方法重写的校验注解（标志）：要求方法名称和形参列表必须与被重写方法一致，否则报错！ 更安全，可读性好，更优雅！
    public void cry(){
        System.out.println("猫会喵喵叫");
    }

    public void selfCat(){
        System.out.println("猫独有功能");
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "Cat{" +
                "name='" + name + '\'' +
                '}';
    }
}

class Dog extends Animal{
    String name="小狗";
    // 方法重写: 方法名称，形参列表必须一样，这个方法就是方法重写。
    // 重写的规范：声明不变，重新实现。
    @Override// 方法重写的校验注解（标志）：要求方法名称和形参列表必须与被重写方法一致，否则报错！ 更安全，可读性好，更优雅！
    public void cry(){
        System.out.println("狗会旺旺叫");
    }

    public void selfDog(){
        System.out.println("狗独有功能");
    }
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "Dog{" +
                "name='" + name + '\'' +
                '}';
    }
}


